<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>react心得 | aiyoudiao</title>
    <meta name="generator" content="VuePress 1.9.10" />
    <link rel="icon" href="/img/blog.ico">
    <script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.1.4/lib/L2Dwidget.min.js"></script> <meta name="description" content="码二~">
    <meta name="keywords" content="前端博客,个人技术博客,前端,前端开发,前端框架,web前端,前端面试题,技术文档,学习,面试,JavaScript,js,ES6,TypeScript,vue,python,css3,html5,Node,git,github,gitee,markdown">
    <meta name="theme-color" content="#11a8cd">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <link rel="preload" href="/assets/css/0.styles.146197cf.css" as="style"><link rel="preload" href="/assets/js/app.bd2fbc77.js" as="script"><link rel="preload" href="/assets/js/3.72c9c947.js" as="script"><link rel="preload" href="/assets/js/116.d5da9b8b.js" as="script"><link rel="preload" href="/assets/js/42.4251ca36.js" as="script"><link rel="prefetch" href="/assets/js/1.4ed4671d.js"><link rel="prefetch" href="/assets/js/10.bd6ddb58.js"><link rel="prefetch" href="/assets/js/100.20d2348f.js"><link rel="prefetch" href="/assets/js/101.ba7b784c.js"><link rel="prefetch" href="/assets/js/102.c3e2dcae.js"><link rel="prefetch" href="/assets/js/103.0f4c50f3.js"><link rel="prefetch" href="/assets/js/104.ef47a111.js"><link rel="prefetch" href="/assets/js/105.2e00f516.js"><link rel="prefetch" href="/assets/js/106.b50e19b9.js"><link rel="prefetch" href="/assets/js/107.e125a8f6.js"><link rel="prefetch" href="/assets/js/108.770493ab.js"><link rel="prefetch" href="/assets/js/109.74766d7b.js"><link rel="prefetch" href="/assets/js/11.f786a5ee.js"><link rel="prefetch" href="/assets/js/110.0b0ee5b4.js"><link rel="prefetch" href="/assets/js/111.835b0e44.js"><link rel="prefetch" href="/assets/js/112.352fa217.js"><link rel="prefetch" href="/assets/js/113.4e908557.js"><link rel="prefetch" href="/assets/js/114.7b77996d.js"><link rel="prefetch" href="/assets/js/115.bdc61268.js"><link rel="prefetch" href="/assets/js/117.35ab1f9f.js"><link rel="prefetch" href="/assets/js/118.517c151d.js"><link rel="prefetch" href="/assets/js/119.f7f49ba8.js"><link rel="prefetch" href="/assets/js/12.3c729a65.js"><link rel="prefetch" href="/assets/js/120.b559598b.js"><link rel="prefetch" href="/assets/js/121.bf8a2f43.js"><link rel="prefetch" href="/assets/js/122.11a0bc97.js"><link rel="prefetch" href="/assets/js/123.2bafdde7.js"><link rel="prefetch" href="/assets/js/124.dc393688.js"><link rel="prefetch" href="/assets/js/125.ed3f389a.js"><link rel="prefetch" href="/assets/js/126.8fd9a57d.js"><link rel="prefetch" href="/assets/js/127.3bf2a1f2.js"><link rel="prefetch" href="/assets/js/128.b9c671d3.js"><link rel="prefetch" href="/assets/js/129.5d331f0d.js"><link rel="prefetch" href="/assets/js/13.7b1a1fe5.js"><link rel="prefetch" href="/assets/js/130.53e4f9c6.js"><link rel="prefetch" href="/assets/js/131.dcc47e1d.js"><link rel="prefetch" href="/assets/js/132.692dcdcd.js"><link rel="prefetch" href="/assets/js/133.e293202c.js"><link rel="prefetch" href="/assets/js/134.593dccf2.js"><link rel="prefetch" href="/assets/js/135.d76d384b.js"><link rel="prefetch" href="/assets/js/136.a519c23c.js"><link rel="prefetch" href="/assets/js/137.b1821288.js"><link rel="prefetch" href="/assets/js/138.5bcea4ef.js"><link rel="prefetch" href="/assets/js/139.076664b0.js"><link rel="prefetch" href="/assets/js/14.35f257b2.js"><link rel="prefetch" href="/assets/js/140.a019e655.js"><link rel="prefetch" href="/assets/js/141.1f70e1c7.js"><link rel="prefetch" href="/assets/js/142.5ed728fd.js"><link rel="prefetch" href="/assets/js/143.1c8cdc78.js"><link rel="prefetch" href="/assets/js/144.b0cb125b.js"><link rel="prefetch" href="/assets/js/145.c0209a76.js"><link rel="prefetch" href="/assets/js/146.551469f4.js"><link rel="prefetch" href="/assets/js/147.1dfd721d.js"><link rel="prefetch" href="/assets/js/148.91d07ef5.js"><link rel="prefetch" href="/assets/js/149.5b88b710.js"><link rel="prefetch" href="/assets/js/15.23bbc29a.js"><link rel="prefetch" href="/assets/js/150.8301107f.js"><link rel="prefetch" href="/assets/js/151.867da089.js"><link rel="prefetch" href="/assets/js/152.935d5046.js"><link rel="prefetch" href="/assets/js/153.f39d8435.js"><link rel="prefetch" href="/assets/js/154.6b9eb2c3.js"><link rel="prefetch" href="/assets/js/155.14283ad4.js"><link rel="prefetch" href="/assets/js/156.2d7c1a2a.js"><link rel="prefetch" href="/assets/js/157.2f28d02f.js"><link rel="prefetch" href="/assets/js/158.151221ae.js"><link rel="prefetch" href="/assets/js/159.ef6d7ffe.js"><link rel="prefetch" href="/assets/js/16.1793aef7.js"><link rel="prefetch" href="/assets/js/160.de54c4ea.js"><link rel="prefetch" href="/assets/js/161.24d4e57c.js"><link rel="prefetch" href="/assets/js/162.632032fe.js"><link rel="prefetch" href="/assets/js/163.fd01cd99.js"><link rel="prefetch" href="/assets/js/164.45f203f5.js"><link rel="prefetch" href="/assets/js/165.aafe4fe1.js"><link rel="prefetch" href="/assets/js/166.1dd1d21c.js"><link rel="prefetch" href="/assets/js/167.5501b3a1.js"><link rel="prefetch" href="/assets/js/168.fbe58b1f.js"><link rel="prefetch" href="/assets/js/169.2cae7f5e.js"><link rel="prefetch" href="/assets/js/17.bbfe63f2.js"><link rel="prefetch" href="/assets/js/170.265f7c9e.js"><link rel="prefetch" href="/assets/js/171.b61f327d.js"><link rel="prefetch" href="/assets/js/172.5d0043fd.js"><link rel="prefetch" href="/assets/js/173.45284bb6.js"><link rel="prefetch" href="/assets/js/174.9130e0c4.js"><link rel="prefetch" href="/assets/js/175.2b38bddd.js"><link rel="prefetch" href="/assets/js/176.9772cf09.js"><link rel="prefetch" href="/assets/js/177.69048ebc.js"><link rel="prefetch" href="/assets/js/178.e10d7ce5.js"><link rel="prefetch" href="/assets/js/179.3789edc0.js"><link rel="prefetch" href="/assets/js/18.0807ded0.js"><link rel="prefetch" href="/assets/js/180.ab675e47.js"><link rel="prefetch" href="/assets/js/181.2e39eff0.js"><link rel="prefetch" href="/assets/js/19.becf5a76.js"><link rel="prefetch" href="/assets/js/2.eb089a4f.js"><link rel="prefetch" href="/assets/js/20.cea59652.js"><link rel="prefetch" href="/assets/js/21.58c43ff1.js"><link rel="prefetch" href="/assets/js/22.f73b825d.js"><link rel="prefetch" href="/assets/js/23.43b13730.js"><link rel="prefetch" href="/assets/js/24.f77f93ca.js"><link rel="prefetch" href="/assets/js/25.7dfaf3fb.js"><link rel="prefetch" href="/assets/js/26.629d28e5.js"><link rel="prefetch" href="/assets/js/27.4fff23ea.js"><link rel="prefetch" href="/assets/js/28.1b8ae389.js"><link rel="prefetch" href="/assets/js/29.d5cce9a0.js"><link rel="prefetch" href="/assets/js/30.961d5519.js"><link rel="prefetch" href="/assets/js/31.121dd1af.js"><link rel="prefetch" href="/assets/js/32.4a3c5df7.js"><link rel="prefetch" href="/assets/js/33.5537f44b.js"><link rel="prefetch" href="/assets/js/34.1d4d4653.js"><link rel="prefetch" href="/assets/js/35.d094209b.js"><link rel="prefetch" href="/assets/js/36.832660c5.js"><link rel="prefetch" href="/assets/js/37.145c3665.js"><link rel="prefetch" href="/assets/js/38.4f369bfe.js"><link rel="prefetch" href="/assets/js/39.ba060044.js"><link rel="prefetch" href="/assets/js/4.66d742f6.js"><link rel="prefetch" href="/assets/js/40.e50e0379.js"><link rel="prefetch" href="/assets/js/41.4ed7617c.js"><link rel="prefetch" href="/assets/js/43.d22b74c4.js"><link rel="prefetch" href="/assets/js/44.59439f9d.js"><link rel="prefetch" href="/assets/js/45.da28bc46.js"><link rel="prefetch" href="/assets/js/46.b8db1176.js"><link rel="prefetch" href="/assets/js/47.7ed16fc7.js"><link rel="prefetch" href="/assets/js/48.c982d5ed.js"><link rel="prefetch" href="/assets/js/49.a7579f55.js"><link rel="prefetch" href="/assets/js/5.08802d7d.js"><link rel="prefetch" href="/assets/js/50.103b5bf6.js"><link rel="prefetch" href="/assets/js/51.0fe9d79a.js"><link rel="prefetch" href="/assets/js/52.9ba31e26.js"><link rel="prefetch" href="/assets/js/53.0e8bc1f0.js"><link rel="prefetch" href="/assets/js/54.9566e517.js"><link rel="prefetch" href="/assets/js/55.a124abae.js"><link rel="prefetch" href="/assets/js/56.d9cf0800.js"><link rel="prefetch" href="/assets/js/57.93599da0.js"><link rel="prefetch" href="/assets/js/58.d943f85b.js"><link rel="prefetch" href="/assets/js/59.50a66488.js"><link rel="prefetch" href="/assets/js/6.a3ea60eb.js"><link rel="prefetch" href="/assets/js/60.21aa3aa3.js"><link rel="prefetch" href="/assets/js/61.6712c00f.js"><link rel="prefetch" href="/assets/js/62.eff3e4b1.js"><link rel="prefetch" href="/assets/js/63.09701d5a.js"><link rel="prefetch" href="/assets/js/64.eb440dec.js"><link rel="prefetch" href="/assets/js/65.aeed0579.js"><link rel="prefetch" href="/assets/js/66.97244c64.js"><link rel="prefetch" href="/assets/js/67.e01c5c24.js"><link rel="prefetch" href="/assets/js/68.21be91ba.js"><link rel="prefetch" href="/assets/js/69.c0849905.js"><link rel="prefetch" href="/assets/js/7.7fd40e91.js"><link rel="prefetch" href="/assets/js/70.b32bbe5d.js"><link rel="prefetch" href="/assets/js/71.0efbc0c7.js"><link rel="prefetch" href="/assets/js/72.ef963181.js"><link rel="prefetch" href="/assets/js/73.ca7dd5db.js"><link rel="prefetch" href="/assets/js/74.4483ede8.js"><link rel="prefetch" href="/assets/js/75.374ab483.js"><link rel="prefetch" href="/assets/js/76.b4a39f08.js"><link rel="prefetch" href="/assets/js/77.6b30c3cd.js"><link rel="prefetch" href="/assets/js/78.15376c33.js"><link rel="prefetch" href="/assets/js/79.3153fcec.js"><link rel="prefetch" href="/assets/js/80.9a88c684.js"><link rel="prefetch" href="/assets/js/81.1e3f842c.js"><link rel="prefetch" href="/assets/js/82.996dbd3d.js"><link rel="prefetch" href="/assets/js/83.955158bf.js"><link rel="prefetch" href="/assets/js/84.71bdc76d.js"><link rel="prefetch" href="/assets/js/85.774e49f2.js"><link rel="prefetch" href="/assets/js/86.bebf32e5.js"><link rel="prefetch" href="/assets/js/87.becdbde1.js"><link rel="prefetch" href="/assets/js/88.49e933f4.js"><link rel="prefetch" href="/assets/js/89.eeceedfd.js"><link rel="prefetch" href="/assets/js/90.3ea6dd12.js"><link rel="prefetch" href="/assets/js/91.62a6a556.js"><link rel="prefetch" href="/assets/js/92.e2ebb8f5.js"><link rel="prefetch" href="/assets/js/93.dcdefe7a.js"><link rel="prefetch" href="/assets/js/94.bf412146.js"><link rel="prefetch" href="/assets/js/95.8deadcdc.js"><link rel="prefetch" href="/assets/js/96.9977087a.js"><link rel="prefetch" href="/assets/js/97.6591f9da.js"><link rel="prefetch" href="/assets/js/98.4db7f75e.js"><link rel="prefetch" href="/assets/js/99.a61462e9.js"><link rel="prefetch" href="/assets/js/vendors~docsearch.2852b102.js"> <link rel="stylesheet" href="/assets/css/0.styles.146197cf.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" width="50" height="50" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="https://p3-passport.byteacctimg.com/img/user-avatar/794fdae4ff249d532da19a3c26d420ed~300x300.image" alt="aiyoudiao" class="logo"> <span class="site-name can-hide">
      aiyoudiao
    </span></a> <div class="links"><div class="sky-switch" data-v-3a03d589><label for="toggle" data-v-3a03d589><input id="toggle" type="checkbox" data-v-3a03d589><div data-v-3a03d589></div></label></div> <div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="笔记" class="dropdown-title"><!----> <span class="title" style="display:;">笔记</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/84633490449/" class="nav-link">
  JavaScript
</a></li><li class="dropdown-item"><!----> <a href="/pages/2331001041/" class="nav-link">
  Vue
</a></li><li class="dropdown-item"><!----> <a href="/pages/18114480448/" class="nav-link">
  React
</a></li><li class="dropdown-item"><!----> <a href="/pages/25236260426/" class="nav-link">
  低代码
</a></li><li class="dropdown-item"><!----> <a href="/pages/35345230523/" class="nav-link">
  线性系统
</a></li><li class="dropdown-item"><!----> <a href="/pages/08313561056/" class="nav-link">
  暂未分类
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="算法与设计" class="dropdown-title"><!----> <span class="title" style="display:;">算法与设计</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/70741550255/" class="nav-link">
  LeetCode
</a></li><li class="dropdown-item"><!----> <a href="/pages/17845450445/" class="nav-link">
  算法
</a></li><li class="dropdown-item"><!----> <a href="/pages/90132170217/" class="nav-link">
  数据结构
</a></li><li class="dropdown-item"><!----> <a href="/pages/50546120212/" class="nav-link">
  设计模式
</a></li><li class="dropdown-item"><!----> <a href="/pages/02344550255/" class="nav-link">
  Other
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="技能" class="dropdown-title"><!----> <span class="title" style="display:;">技能</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/82158160216/" class="nav-link">
  PMP
</a></li><li class="dropdown-item"><!----> <a href="/pages/41858590259/" class="nav-link">
  Office
</a></li><li class="dropdown-item"><!----> <a href="/pages/02359360236/" class="nav-link">
  面试
</a></li><li class="dropdown-item"><!----> <a href="/pages/73600130213/" class="nav-link">
  Bash
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="历程" class="dropdown-title"><!----> <span class="title" style="display:;">历程</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/83857320232/" class="nav-link">
  流年往事
</a></li><li class="dropdown-item"><!----> <a href="/pages/93419130213/" class="nav-link">
  经验片段
</a></li><li class="dropdown-item"><!----> <a href="/pages/99744220322/" class="nav-link">
  读书杂感
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="首页" class="dropdown-title"><!----> <span class="title" style="display:;">首页</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">
  归档
</a></li><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">
  分类
</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">
  标签
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="其它" class="dropdown-title"><!----> <span class="title" style="display:;">其它</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/02657130213/" class="nav-link">
  简介
</a></li><li class="dropdown-item"><!----> <a href="/pages/5390102042/" class="nav-link">
  收藏
</a></li><li class="dropdown-item"><!----> <a href="/pages/32309510451/" class="nav-link">
  有趣
</a></li><li class="dropdown-item"><!----> <a href="/pages/23313210521/" class="nav-link">
  文档
</a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="/img/mar.jpg"> <div class="blogger-info"><h3>码二</h3> <span>扫微信二维码，认识一下码二吧😉。</span></div></div> <nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="笔记" class="dropdown-title"><!----> <span class="title" style="display:;">笔记</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/84633490449/" class="nav-link">
  JavaScript
</a></li><li class="dropdown-item"><!----> <a href="/pages/2331001041/" class="nav-link">
  Vue
</a></li><li class="dropdown-item"><!----> <a href="/pages/18114480448/" class="nav-link">
  React
</a></li><li class="dropdown-item"><!----> <a href="/pages/25236260426/" class="nav-link">
  低代码
</a></li><li class="dropdown-item"><!----> <a href="/pages/35345230523/" class="nav-link">
  线性系统
</a></li><li class="dropdown-item"><!----> <a href="/pages/08313561056/" class="nav-link">
  暂未分类
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="算法与设计" class="dropdown-title"><!----> <span class="title" style="display:;">算法与设计</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/70741550255/" class="nav-link">
  LeetCode
</a></li><li class="dropdown-item"><!----> <a href="/pages/17845450445/" class="nav-link">
  算法
</a></li><li class="dropdown-item"><!----> <a href="/pages/90132170217/" class="nav-link">
  数据结构
</a></li><li class="dropdown-item"><!----> <a href="/pages/50546120212/" class="nav-link">
  设计模式
</a></li><li class="dropdown-item"><!----> <a href="/pages/02344550255/" class="nav-link">
  Other
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="技能" class="dropdown-title"><!----> <span class="title" style="display:;">技能</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/82158160216/" class="nav-link">
  PMP
</a></li><li class="dropdown-item"><!----> <a href="/pages/41858590259/" class="nav-link">
  Office
</a></li><li class="dropdown-item"><!----> <a href="/pages/02359360236/" class="nav-link">
  面试
</a></li><li class="dropdown-item"><!----> <a href="/pages/73600130213/" class="nav-link">
  Bash
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="历程" class="dropdown-title"><!----> <span class="title" style="display:;">历程</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/83857320232/" class="nav-link">
  流年往事
</a></li><li class="dropdown-item"><!----> <a href="/pages/93419130213/" class="nav-link">
  经验片段
</a></li><li class="dropdown-item"><!----> <a href="/pages/99744220322/" class="nav-link">
  读书杂感
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="首页" class="dropdown-title"><!----> <span class="title" style="display:;">首页</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/archives/" class="nav-link">
  归档
</a></li><li class="dropdown-item"><!----> <a href="/categories/" class="nav-link">
  分类
</a></li><li class="dropdown-item"><!----> <a href="/tags/" class="nav-link">
  标签
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="其它" class="dropdown-title"><!----> <span class="title" style="display:;">其它</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/pages/02657130213/" class="nav-link">
  简介
</a></li><li class="dropdown-item"><!----> <a href="/pages/5390102042/" class="nav-link">
  收藏
</a></li><li class="dropdown-item"><!----> <a href="/pages/32309510451/" class="nav-link">
  有趣
</a></li><li class="dropdown-item"><!----> <a href="/pages/23313210521/" class="nav-link">
  文档
</a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>JavaScript</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>vue</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>react</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><section class="sidebar-group collapsable is-sub-group depth-1"><p class="sidebar-heading open"><span>16_4</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/pages/18114480448/" class="sidebar-link">React16_4整理-开篇</a></li><li><a href="/pages/78144320432/" class="sidebar-link">React16_4整理-TodoList</a></li><li><a href="/pages/7981309049/" class="sidebar-link">React16_4整理-上阶</a></li><li><a href="/pages/4241004044/" class="sidebar-link">React16_4整理-Redux开篇</a></li><li><a href="/pages/2765901041/" class="sidebar-link">React16_4整理-Redux上阶</a></li><li><a href="/pages/53933290429/" class="sidebar-link">React16_4整理-实战</a></li></ul></section></li><li><a href="/pages/2541802042/" aria-current="page" class="active sidebar-link">react心得</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/pages/2541802042/#前言" class="sidebar-link">前言</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#虚拟dom" class="sidebar-link">虚拟dom</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#fiber比虚拟dom更快" class="sidebar-link">fiber比虚拟dom更快</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#性能提升" class="sidebar-link">性能提升</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#fiber-怎么做到的" class="sidebar-link">fiber 怎么做到的?</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#requestidlecallback" class="sidebar-link">requestIdleCallback</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#将虚拟dom转成fiber对象" class="sidebar-link">将虚拟dom转成fiber对象</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#feiber-的流程-迷你流程" class="sidebar-link">feiber 的流程（迷你流程）</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#react-生命周期" class="sidebar-link">React 生命周期</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/pages/2541802042/#_16-0之前" class="sidebar-link">16.0之前</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#_16-0之后" class="sidebar-link">16.0之后</a></li></ul></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#diff算法" class="sidebar-link">diff算法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/pages/2541802042/#_16-0之前-2" class="sidebar-link">16.0之前</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#_16-0之后-2" class="sidebar-link">16.0之后</a></li></ul></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#react-状态管理" class="sidebar-link">React 状态管理</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/pages/2541802042/#flux" class="sidebar-link">flux</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#redux" class="sidebar-link">redux</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#flux-和-redux对比" class="sidebar-link">flux 和 redux对比</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#mbox" class="sidebar-link">mbox</a></li></ul></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#hooks" class="sidebar-link">hooks</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/pages/2541802042/#usestate" class="sidebar-link">useState</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#useeffect" class="sidebar-link">useEffect</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#uselayouteffect" class="sidebar-link">useLayoutEffect</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#useeffect-和-uselayouteffect" class="sidebar-link">useEffect 和 useLayoutEffect</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#usememo" class="sidebar-link">useMemo</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#usecallback" class="sidebar-link">useCallback</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#useref" class="sidebar-link">useRef</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#usereducer" class="sidebar-link">useReducer</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#usecontext" class="sidebar-link">useContext</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#自定义hook" class="sidebar-link">自定义Hook</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#class和hook的对比" class="sidebar-link">class和hook的对比</a></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#react性能优化" class="sidebar-link">react性能优化</a></li></ul></li><li class="sidebar-sub-header"><a href="/pages/2541802042/#总结" class="sidebar-link">总结</a></li></ul></li><li><a href="/pages/56216400440/" class="sidebar-link">react设计的哲学</a></li><li><a href="/pages/64353330433/" class="sidebar-link">react上手知识点(上篇)</a></li><li><a href="/pages/67517390439/" class="sidebar-link">react上手知识点(下篇)</a></li><li><a href="/pages/21029430543/" class="sidebar-link">antd</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>低代码</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>读书会</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>线性代数</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>docker</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>auto</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>杂记</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div><main class="page"> <div class="theme-vdoing-wrapper bg-style-1"><div class="articleInfo-wrap" data-v-18fb2c02><div class="articleInfo" data-v-18fb2c02><ul class="breadcrumbs" data-v-18fb2c02><li data-v-18fb2c02><a href="/" title="首页" class="iconfont icon-home router-link-active" data-v-18fb2c02></a></li> <li data-v-18fb2c02><a href="/categories/?category=%E7%AC%94%E8%AE%B0" title="分类" data-v-18fb2c02>
          笔记
        </a></li> <li data-v-18fb2c02><a href="/categories/?category=react" title="分类" data-v-18fb2c02>
          react
        </a></li> <!----></ul> <div class="info" data-v-18fb2c02><div title="作者" class="author iconfont icon-touxiang" data-v-18fb2c02><a href="javascript:;" data-v-18fb2c02>aiyoudiao</a></div> <div title="创建时间" class="date iconfont icon-riqi" data-v-18fb2c02><a href="javascript:;" data-v-18fb2c02>2022-04-13</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-content"></div></div></div> <h1><!----> <span>
            react心得
          </span></h1> <div class="theme-vdoing-content content__default"><h2 id="前言"><a href="#前言" class="header-anchor">#</a> 前言</h2> <p>React 就干两件事，打造用户界面，响应各种事件。16.0版本提出fiber，16.8版本提出hooks。</p> <p>React原来是php项目，后来改了编译器，换成js来编译，然后加入虚拟dom。所以React只做两件事，一件事是渲染ui，一件事是响应事件。mvc和mvvm都是早些年angular的设计理念。react并不是什么mvvm和mvc，它只是一个很小的东西，只做那两件事儿。它只是个工具。backbone才是真正的mvc，它是模仿java的spring，挪到前端来了。</p> <h2 id="虚拟dom"><a href="#虚拟dom" class="header-anchor">#</a> 虚拟dom</h2> <p>json结构的描述，一个带有规则定义的js的对象(schema 数据模型)。比如你定义的菜单按钮权限的json，比如你定义低代码的json配置文件 如拖拉拽的图表生成器。</p> <p>react的虚拟dom就是一个json描述的数据结构，一个能够映射出真实dom的数据schema。</p> <h2 id="fiber比虚拟dom更快"><a href="#fiber比虚拟dom更快" class="header-anchor">#</a> fiber比虚拟dom更快</h2> <p>以前的虚拟dom是一颗树，操作这颗树的时间复杂度是O(n^3)，而且递归一棵树是没法暂停的。这样当树结构过大，必须得遍历时，那么页面会发生严重的卡顿。<br>
而fiber是一个链表，操作一个链表的时间复杂度是O(n)，而且fiber是可以暂停的，它不容易造成卡顿。</p> <h2 id="性能提升"><a href="#性能提升" class="header-anchor">#</a> 性能提升</h2> <p>react提升性能，使用16.0之前的版本，使用虚拟dom时，不改变版本的情况下，要减少跨层级的移动、删除节点的业务。<br>
因为那样会很卡，虚拟dom是一颗树，时间复杂度是O(n^3)，例如排序，就可以使用第三方别的库来做，改变dom的顺序一般不需要改变dom的内容，react的强项是改变dom的内容。</p> <h2 id="fiber-怎么做到的"><a href="#fiber-怎么做到的" class="header-anchor">#</a> fiber 怎么做到的?</h2> <p>利用浏览器空闲时间执行，不会长时间占用主线程。<br>
将对比、更新dom的操作碎片化了。diff完成dom在内存中已经存在了，只是没有放在页面中，存到了fiber对象中的stateNode中去了。<br>
碎片化的任务，可以根据需要来被暂停。</p> <h2 id="requestidlecallback"><a href="#requestidlecallback" class="header-anchor">#</a> requestIdleCallback</h2> <p>这个是浏览器提供的api，可以利用浏览器空闲时间执行任务。fiber就是借用这个api外加它的任务调度来做的。</p> <h2 id="将虚拟dom转成fiber对象"><a href="#将虚拟dom转成fiber对象" class="header-anchor">#</a> 将虚拟dom转成fiber对象</h2> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649842018577-8f88160c-11db-4f95-bac9-3dd1f622f3c1.png" alt=""></p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649842256200-75387334-938b-49d1-88b6-3198d521042e.png" alt=""></p> <p>会将虚拟dom对象构建成fiber对象，根据fiber对象渲染成真实dom。</p> <h2 id="feiber-的流程-迷你流程"><a href="#feiber-的流程-迷你流程" class="header-anchor">#</a> feiber 的流程（迷你流程）</h2> <div class="language-tsx extra-class"><pre class="language-tsx"><code><span class="token comment">// 创建任务队列</span>
<span class="token keyword">const</span> taskQueue <span class="token operator">=</span> <span class="token function">createTaskQueue</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

<span class="token comment">//空闲时间执行的具体方法</span>
<span class="token keyword">const</span> <span class="token function-variable function">performTask</span> <span class="token operator">=</span> deadline <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//执行务workLoop方法后续补充 </span>
    <span class="token function">workLoop</span><span class="token punctuation">(</span>deadline<span class="token punctuation">)</span>
    <span class="token comment">//实现持续调用</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>subTask <span class="token operator">||</span> <span class="token operator">!</span>taskQueue<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">requestIdleCallback</span><span class="token punctuation">(</span>performTask<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
<span class="token comment">// 暴露的render方法</span>
<span class="token keyword">export</span> <span class="token keyword">const</span> <span class="token function-variable function">render</span> <span class="token operator">=</span> <span class="token punctuation">(</span>element<span class="token punctuation">,</span> dom<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//1.添加任务 -&gt; 构建fiber对象 </span>
    taskQueue<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
        dom<span class="token punctuation">,</span>
        props<span class="token operator">:</span> <span class="token punctuation">{</span> children<span class="token operator">:</span> element <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>
    <span class="token comment">//2.指定浏览器空闲时间执行performTask 方法 </span>
    <span class="token function">requestIdleCallback</span><span class="token punctuation">(</span>performTask<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-tsx extra-class"><pre class="language-tsx"><code><span class="token comment">// 子任务</span>
<span class="token keyword">let</span> subTask <span class="token operator">=</span> <span class="token keyword">null</span>
<span class="token comment">//commit操作标志</span>
<span class="token keyword">let</span> pendingCommit <span class="token operator">=</span> <span class="token keyword">null</span>

<span class="token keyword">const</span> <span class="token function-variable function">workLoop</span> <span class="token operator">=</span> deadline <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">//1.构建根对象 </span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>subTask<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        subTask <span class="token operator">=</span> <span class="token function">getFirstTask</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//2.通过while循环构建其余对象</span>
    <span class="token keyword">while</span> <span class="token punctuation">(</span>subTask <span class="token operator">&amp;&amp;</span> deadline<span class="token punctuation">.</span><span class="token function">timeRemaining</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">&gt;</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        subTask <span class="token operator">=</span> <span class="token function">executeTask</span><span class="token punctuation">(</span>subTask<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
    <span class="token comment">//3.执行commit操作。实现Dom挂载 </span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>pendingCommit<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">commitAllwork</span><span class="token punctuation">(</span>pendingCommit<span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><div class="language-tsx extra-class"><pre class="language-tsx"><code><span class="token keyword">const</span> <span class="token function-variable function">getFirstTask</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token comment">// 获取任务队列中的任务</span>
    <span class="token keyword">const</span> task <span class="token operator">=</span> taskQueue<span class="token punctuation">.</span><span class="token function">pop</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token comment">//返回Fiber对象 </span>
    <span class="token keyword">return</span> <span class="token punctuation">{</span>
        props<span class="token operator">:</span> task<span class="token punctuation">.</span>props<span class="token punctuation">,</span> 
        stateNode<span class="token operator">:</span> task<span class="token punctuation">.</span>dom<span class="token punctuation">,</span>
        <span class="token comment">//代表拟Dom挂载的节点 </span>
        tag<span class="token operator">:</span> <span class="token string">&quot;host_root&quot;</span><span class="token punctuation">,</span> 
        effects<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span> 
        child<span class="token operator">:</span> <span class="token keyword">null</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="react-生命周期"><a href="#react-生命周期" class="header-anchor">#</a> React 生命周期</h2> <p>react只是删除了那几个生命周期函数，并没有删除那几个生命周期，生命周期函数在16.0之后发生了变化。生命周期的变化是加入fiber之后，才发生了那些变化。</p> <h3 id="_16-0之前"><a href="#_16-0之前" class="header-anchor">#</a> 16.0之前</h3> <p>初始化=》挂载props=》初始化state=》render dom=》完成<br>
获取数据完毕=》更新state=》diff=》render dom =》完成</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843249995-335e7b10-a0cf-4507-a38d-43f69633a0ee.png" alt=""></p> <p>用的比较多的是componentDidMount。<br>
shouldComponentUpdate 是手动干预提升react性能的唯一手段。<br>
如果你能手动控制每一个组件的shouldComponentUpdate，就算你不用fiber，就算虚拟dom是树，你也未必慢。<br>
所以这也体现了有经验的人写react和没经验的人写react是不一样的。</p> <h3 id="_16-0之后"><a href="#_16-0之后" class="header-anchor">#</a> 16.0之后</h3> <p>之前是树，循环加递归的去判断它是否发生变化。现在是链表，循环加打打标记的来判断它是否发生变化。</p> <p>fiber的diff算法是在render中执行的，为了保证应对fiber的链式渲染，所以render之前的那些方法。<br>
比如 componentWillMount、componentWillReceiveProps、componentWillUpdate，它们就不需要了，因为它可能会在render之前改变state属性，会造成优先级不正确的问题。<br>
于是react觉得这些方法会存在风险，所以把它们直接干掉了。不过shouldComponentUpdate保留下来了，它不会改变state。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843336874-5ec5908f-66a0-4ceb-8689-1020695be976.png" alt=""></p> <p>getDerivedStateFromProps 允许你在render之前改一下state，返回null就不更新state。<br>
getSnapshotBeforeUpdate 可以获得上一次真实渲染的快照。</p> <h2 id="diff算法"><a href="#diff算法" class="header-anchor">#</a> diff算法</h2> <h3 id="_16-0之前-2"><a href="#_16-0之前-2" class="header-anchor">#</a> 16.0之前</h3> <p>只要类型和key中任何一个发生变化，就算你节点变化。<br>
树的节点遍历，只需要遍历一遍就行了，但是把树这个结构的遍历应用到diff算法中就是O(n^3)，因为它进行三层遍历，分别时tree diff、component diff、element diff。</p> <p>针对树结构（tree diff）：只要存在UI层的DOM节点跨层级的操作，直接干掉，重新创建。<br>
针对组件结构（component diff）：拥有相同嘞的两个组件生成相似的树形结构，拥有不同类的两个组件会生成不同的树形结构。<br>
针对元素结构（element diff）：对于同一层级的一组节点，使用具有唯一性的id区分（key属性来区分）。</p> <h3 id="_16-0之后-2"><a href="#_16-0之后-2" class="header-anchor">#</a> 16.0之后</h3> <p>fiber的diff是可中断的，其实就是循环三遍，时间复杂度其实是O（3n）去除系数就是O(n)。</p> <p>先通过state计算出新的fiber节点。<br>
对比节点的tag和key确定节点操作（修改，删除，新增，移动）。移动是最复杂的。<br>
用effectTag标记出fiber对象，第一次循环结束之后，它就能知道所有节点都干了啥。<br>
收集所有标记的fiber对象，形成effctList。没有打上标记的，就表示它没变，就不用进行接下来的循环操作了。<br>
然后在commit阶段一次性处理完，处理完所有变化的节点。</p> <h4 id="单节点"><a href="#单节点" class="header-anchor">#</a> 单节点</h4> <p>新旧相同 不变<br>
新旧不同 更新
新有旧无 新增</p> <h4 id="多节点"><a href="#多节点" class="header-anchor">#</a> 多节点</h4> <p>新旧相同 不变
新有旧无 新增
新无旧有 删除
新旧顺序不同 位置移动或者互换
新旧顺序不同并且旧有新无 先删除再位置移动或者互换</p> <h2 id="react-状态管理"><a href="#react-状态管理" class="header-anchor">#</a> React 状态管理</h2> <p>React 默认没带数据流（状态管理），那些实现了数据流的库不光可以在react中使用，也可以在vue中使用。<br>
每一个好的东西都有它自己适合的范围。</p> <h3 id="flux"><a href="#flux" class="header-anchor">#</a> flux</h3> <p>UI产生动作消息，将动作传递给分发器。（这个动作就是 比如 点击一个按钮或者ajax返回数据）<br>
分发器广播给所有store。（以广播的方式告诉所有store。）<br>
订阅的store做出反应，传递新的state给UI。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843709869-2ba095d1-8b7f-455e-ae81-bb6578c4a974.png" alt="">
在react中flux叫rflux，flux中有多个store。</p> <h3 id="redux"><a href="#redux" class="header-anchor">#</a> redux</h3> <p>redux与flux不同，它只有一个单一的store。整个应用的state存储在一个单一的store树中。</p> <p>state状态为只读，你不能直接修改state，应该要通过action触发state修改。</p> <p>得使用纯函数进行状态修改，需要你写reducers纯函数来进行处理，reducer通过当前状态树和action来进行计算，返回一个新的state。（这个reducer可以当它是一个merge函数，merge完了之后返回一个新的state来更新掉那个旧的。）</p> <p>不过如果一个应用的state都存到一个store中，那么效率就会很低，于是它提出了一个分支的概念，不同的state放到不同的分支上。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843751735-73a9919c-25f6-48ab-a8fd-275c55c3c1e9.png" alt=""></p> <p>redux：<a href="https://react-redux.js.org/" target="_blank" rel="noopener noreferrer">https://react-redux.js.org/<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h3 id="flux-和-redux对比"><a href="#flux-和-redux对比" class="header-anchor">#</a> flux 和 redux对比</h3> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843801448-4ad012b4-17bf-41a4-b4a3-8f6028064868.png" alt=""></p> <p>flux和redux都可以作为react的状态管理，flux是多store，redux是单store。<br>
flux有调度器来进行事件处理，redux依赖reducer来实现事件处理。<br>
flux的state可以直接修改，redux 的state不能直接修改，要通过reducer进行state的merge方式来产生一个新的state。</p> <h3 id="mbox"><a href="#mbox" class="header-anchor">#</a> mbox</h3> <p>mbox是一个状态管理机制，是全自动的，action一改变state，views上就直接发生变化，不需要你像redux一样去写reducer函数了。<br>
定义状态并使其可观察，使用修饰符@observer来使其可观察。<br>
创建视图以响应状态变化。<br>
更改状态（自动响应UI变化）。</p> <p>mobx：<a href="https://cn.mobx.js.org/" target="_blank" rel="noopener noreferrer">https://cn.mobx.js.org/<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <h2 id="hooks"><a href="#hooks" class="header-anchor">#</a> hooks</h2> <p>组件之间复用状态逻辑很难，得使用redux或mox来实现状态逻辑的复用。<br>
复杂组件变的难以理解<br>
难以理解的class</p> <p>hooks的使用降低了理解成本，也让react组件更像是函数。<br>
它没有什么魔法，就是数组，还是两个数组，一个存所有state，一个存所有的state的setter。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649843957507-c9975ec3-c376-4e9a-90f8-0e224f3d58f6.png" alt=""></p> <h3 id="usestate"><a href="#usestate" class="header-anchor">#</a> useState</h3> <p>用两个数组实现的，一个存所有的state，另一个存state的setter。<br>
所以如果是在循环和判断的逻辑下用useState，会导致state和setter错乱，最好在函数顶部使用。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649844013825-ff50979a-3fac-41a4-b09e-8b510012ffa9.png" alt=""></p> <h3 id="useeffect"><a href="#useeffect" class="header-anchor">#</a> useEffect</h3> <p>治病的过程中产生了额外的影响。<br>
useEffect 就是在你初始化之后，再次render之前，产生的额外影响。比如 数组的slice 和 splice函数。</p> <p>useEffect 函数就是hooks中副作用函数，第一个参数就是callback函数，第二个参数是一个数组，就是你要监听的变量。如果你放一个空数组，它会起到一个componentDidMount的作用，没有监听任何变量，那么就不存在任何变化，那么就只会执行一次。<br>
如果你想销毁state，可以在useEffect函数return的第一个函数。</p> <h3 id="uselayouteffect"><a href="#uselayouteffect" class="header-anchor">#</a> useLayoutEffect</h3> <p>useEffect是在浏览器渲染后执行，useLayoutEffect是在浏览器渲染前执行。<br>
官方不建议你是用它，但是官方还是出了这个hooks。<br>
useLayoutEffect 主要在useEffect函数结果不满意的时候才被用到，一般是当处理dom改变带的副作用，这个hook执行时，浏览器并未对dom进行渲染，相对于useEffect执行要早。</p> <h3 id="useeffect-和-uselayouteffect"><a href="#useeffect-和-uselayouteffect" class="header-anchor">#</a> useEffect 和 useLayoutEffect</h3> <p>useEffect 和 useLayoutEffect在mount和update阶段执行方法一样，传参不一样。<br>
useEffect异步执行，而useLayoutEffect同步执行。<br>
Effect 用 HookPassive 标记useEffect，用HookLayout标记useLayoutEffect。</p> <h3 id="usememo"><a href="#usememo" class="header-anchor">#</a> useMemo</h3> <p>老的是memo，新的hooks中是useMemo。传递⼀个函数和依赖项，当依赖项发⽣变
化，执⾏函数，该函数需要返回⼀个值</p> <p>类似于vue中的computed 计算属性，但是写法不同。</p> <h3 id="usecallback"><a href="#usecallback" class="header-anchor">#</a> useCallback</h3> <p>返回一个函数，当监听的数据发生变化，才会执行回调函数。</p> <h3 id="useref"><a href="#useref" class="header-anchor">#</a> useRef</h3> <p>相当于一个id的作用，id能够找真实dom，这个可以用来找虚拟dom，可以拿到fiber对象。</p> <h3 id="usereducer"><a href="#usereducer" class="header-anchor">#</a> useReducer</h3> <p>redux、mbox是完整独立的状态管理方案。未必一定是为react打造的，它们只是和react进行了结合。react本身关注的是渲染UI和响应各种事件，为了提高效率，所以官方才出了这个hook。</p> <p>聚合参数，以达到开发效率的提升以及代码的简洁。<br>
useReducer在re-render时候不会改变存储位置，state作为props传给子component不会产生diff的效率问题（useMemo优化）</p> <p>useReducer也许是替代useState，由于数据并未能共享，所以 并不能替代redux、mbox。</p> <h3 id="usecontext"><a href="#usecontext" class="header-anchor">#</a> useContext</h3> <p>useContext能够产生一个Provider，能够使得你的Provider标签下面所有的组件共享一组数据。类似于一个局部的window哟。</p> <h3 id="自定义hook"><a href="#自定义hook" class="header-anchor">#</a> 自定义Hook</h3> <p>自定义的hook其实并不是hook，只是一个自定义的函数，只是它用了use标识开头，看起来像是符合了Hook的规则。<br>
useXXX 和vue3的composition api很像。</p> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649844162647-3d124fce-2daa-4298-8381-9b58a7b8aa20.png" alt=""></p> <h3 id="class和hook的对比"><a href="#class和hook的对比" class="header-anchor">#</a> class和hook的对比</h3> <p><img src="https://gitee.com/aiyoudiao/images/raw/master/2022/04/13/1649844184866-39e4fee2-4eea-4d0f-9790-aa8eb2159717.png" alt=""></p> <p>官方不考虑废除class。class只是一种编程方式，在16.0之后依然是使用fiber和新的diff算法，效率上并不比class差，提升效率使用的是fiber。</p> <p>hooks延申的写法太多，也许页面中一堆useState，可能显得比较乱，有时很难搞清楚这些state之间的关联，当然你可以尝试根据相应的业务逻辑做一下聚合。容易发生内存泄露。<br>
class语法虽然难以理解，都是代码逻辑比较清晰，它面向对象嘛。</p> <p>hook往往作为那种单节点组件，比如几十个表单域。最后使用class来写一个整个表单的数据流的入口。</p> <p>useEffect是浅监听。</p> <h3 id="react性能优化"><a href="#react性能优化" class="header-anchor">#</a> react性能优化</h3> <ol><li>避免跨层级的移动</li> <li>sholudComponentUpdate</li> <li>Memo/useMemo</li> <li>useReducer</li></ol> <h2 id="总结"><a href="#总结" class="header-anchor">#</a> 总结</h2> <p>看changelog的方法：看当中长的、大版本的，看你能看懂的，看不懂的就过。你能看懂，你还想了解的更深，点击#中的issue，然后你还可以通过有道的划词翻译，查看具体的译文。关键节点一定要记到时间点，至少要记到月份。</p> <p>react 的fiber 让 react得到了一个质的提升，但react的生命周期并没有很大的变化，废弃掉了一些生命周期钩子，这些生命周期应该还有，只是不暴露到外面，防止你影响fiber的正常运行。</p> <p>看源码：github桌面版，能够看到那些changelog的具体变化。具体的代码用vscode来看。<br>
看源码不要广泛的去看，文件太多不那么容易看，看源码要学会放下，要学会存疑，看不懂就假想它是一个符号，你不用关系这个符号是干什么的，只需要知道这个符号是干什么的。<br>
先看你认识的，你感兴趣的，不认识的先别管。官方有一些demo的，比如你要学什么，你通过看那些大牛写的demo，就能够学会怎么用以及部分的原理。
一个不恰当的例子吧，它和看毛片类似，先看你感兴趣的地方，然后再看看其它地方有没有漏掉的，你不可能每一部都从头看到尾。<br>
先看react-dom，react-dom中没有fiber相关的内容，fiber相关的在react-reconciler中。</p> <p>react的diff算法在fiber之后也有了很大的变化，之前三层遍历，分别时tree diff、component diff、element diff。<br>
而现在fiber的diff是可中断的，其实就是循环三遍，时间复杂度其实是O（3n）去除系数就是O(n)。</p> <p>react的状态管理有很多 flux、redux、mbox等等，没有谁好谁坏，只是每一个好的东西都有它自己适合的范围。</p> <p>react的hooks降低了理解成本，也让react组件更像是函数。它没有什么魔法，就是数组，还是两个数组，一个存所有state，一个存所有的state的setter。用到了闭包，容易发生内存泄露。<br>
class语法虽然难以理解，都是代码逻辑比较清晰，毕竟是面向对象，官方并没有废除class。<br>
hooks往往作为那种单节点组件，比如几十个表单域。最后使用class来写一个整个表单的数据流的入口。</p> <p>就算你使用了老的vdom，最终也会被转成fiber dom的，fiber dom就是react新一代的vdom。</p></div></div> <div class="page-edit"><!----> <div class="tags"><a href="/tags/?tag=react" title="标签">#react</a></div> <div class="last-updated"><span class="prefix">上次更新时间:</span> <span class="time">10年18月2023日 01时57分53秒</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/pages/53933290429/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">React16_4整理-实战</div></a> <a href="/pages/56216400440/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">react设计的哲学</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/pages/53933290429/" class="prev">React16_4整理-实战</a></span> <span class="next"><a href="/pages/56216400440/"> react设计的哲学 </a>
        →
      </span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/pages/45343271027/"><div>01.数据结构导论一览.md</div></a> <span>10-16</span></dt></dl><dl><dd>02</dd> <dt><a href="/pages/38850370637/"><div>30.2023年06月04日.md</div></a> <span>06-04</span></dt></dl><dl><dd>03</dd> <dt><a href="/pages/74707370537/"><div>08.与测量相关.md</div></a> <span>05-06</span></dt></dl> <dl><dd></dd> <dt><a href="/archives/" class="more">更多文章&gt;</a></dt></dl></div></div> </main></div> <div class="footer"><!----> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
    | Copyright © 2017-2023
    <span class="link">aiyoudiao 码二</span> <span>备案号：</span> <a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank" title="备案号">鄂ICP备2022002654号-1</a></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-fanhuidingbu" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div></div> <!----> <!----> <!----></div><div class="global-ui"><div></div><APlayer audio="" fixed="true" theme="#b7daff" loop="loop" order="list" preload="auto" volume="0.7" mutex="true" lrc-type="3" list-max-height="250" storage-name="vuepress-plugin-meting" id="aplayer-fixed"></APlayer><div id="VuepressPluginLive2d"></div></div></div>
    <script src="/assets/js/app.bd2fbc77.js" defer></script><script src="/assets/js/3.72c9c947.js" defer></script><script src="/assets/js/116.d5da9b8b.js" defer></script><script src="/assets/js/42.4251ca36.js" defer></script>
  </body>
</html>
